package com.atguigu.gmall.payment.service.impl;

import com.atguigu.gmall.common.constant.MqConst;
import com.atguigu.gmall.common.service.RabbitService;
import com.atguigu.gmall.enums.model.PaymentStatus;
import com.atguigu.gmall.enums.model.PaymentType;
import com.atguigu.gmall.order.client.OrderFeignClient;
import com.atguigu.gmall.order.model.OrderInfo;
import com.atguigu.gmall.payment.mapper.PaymentInfoMapper;
import com.atguigu.gmall.payment.model.PaymentInfo;
import com.atguigu.gmall.payment.service.PaymentInfoService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;

/**
 * @author: atguigu
 * @create: 2023-01-28 15:49
 */
@Service
public class PaymentInfoServiceImpl extends ServiceImpl<PaymentInfoMapper, PaymentInfo> implements PaymentInfoService {

    @Autowired
    private RabbitService rabbitService;

    @Autowired
    private OrderFeignClient orderFeignClient;

    /**
     * 新增本地交易记录
     *
     * @param orderInfo   订单信息 基于订单构建本地交易记录
     * @param paymentType 支付类型（1：微信 2：支付宝）
     */
    @Override
    public void savePaymentInfo(OrderInfo orderInfo, String paymentType) {
        //1.根据订单信息中订单编号查询订单是否已有记录  存在：忽略 不存在：新增
        LambdaQueryWrapper<PaymentInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PaymentInfo::getOutTradeNo, orderInfo.getOutTradeNo());
        queryWrapper.eq(PaymentInfo::getPaymentType, paymentType);
        int count = this.count(queryWrapper);
        if (count > 0) return;
        //2.基于传入参数订单信息构建本地交易记录对象，并且保存
        PaymentInfo paymentInfo = new PaymentInfo();
        paymentInfo.setOutTradeNo(orderInfo.getOutTradeNo());
        paymentInfo.setOrderId(orderInfo.getId());
        paymentInfo.setUserId(orderInfo.getUserId());
        paymentInfo.setPaymentType(paymentType);
        //paymentInfo.setTotalAmount(orderInfo.getTotalAmount());//正式
        paymentInfo.setTotalAmount(new BigDecimal("0.01"));//测试
        paymentInfo.setSubject(orderInfo.getTradeBody());
        paymentInfo.setPaymentStatus(PaymentStatus.UNPAID.name());
        this.save(paymentInfo);
    }

    /**
     * 获取本地交易支付记录
     *
     * @param outTradeNo  订单编号
     * @param paymentType 支付方式
     * @return
     */
    @Override
    public PaymentInfo getPaymentInfo(String outTradeNo, String paymentType) {
        LambdaQueryWrapper<PaymentInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PaymentInfo::getOutTradeNo, outTradeNo);
        queryWrapper.eq(PaymentInfo::getPaymentType, paymentType);
        return this.getOne(queryWrapper);
    }

    /**
     * 修改本地交易记录状态
     *
     * @param outTradeNo  订单编号
     * @param paymentType 支付方式
     * @param paramsMap   支付宝回调参数
     */
    @Override
    public void paySuccess(String outTradeNo, String paymentType, Map<String, String> paramsMap) {
        //1.修改本地支付表状态为已支付
        LambdaUpdateWrapper<PaymentInfo> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(PaymentInfo::getOutTradeNo, outTradeNo);
        updateWrapper.eq(PaymentInfo::getPaymentType, paymentType);

        updateWrapper.set(PaymentInfo::getPaymentStatus, PaymentStatus.PAID.name());
        updateWrapper.set(PaymentInfo::getTradeNo, paramsMap.get("trade_no"));
        updateWrapper.set(PaymentInfo::getCallbackTime, new Date());
        updateWrapper.set(PaymentInfo::getCallbackContent, paramsMap.toString());
        this.update(updateWrapper);
        //2.todo 发送修改订单状态消息到MQ 通知 订单微服务
        PaymentInfo paymentInfo = this.getPaymentInfo(outTradeNo, paymentType);
        rabbitService.sendMessage(MqConst.EXCHANGE_DIRECT_PAYMENT_PAY, MqConst.ROUTING_PAYMENT_PAY, paymentInfo.getOrderId());
    }

    /**
     * 修改本地交易记录状态为关闭
     *
     * @param orderId
     */
    @Override
    public void closePayment(Long orderId) {
        //1.根据条件订单ID，支付方式查询本地交易记录
        PaymentInfo paymentInfo = this.getPaymentInfo(orderId, PaymentType.ALIPAY.name());
        if (paymentInfo != null) {
            //2.修改状态为关闭
            paymentInfo.setPaymentStatus(PaymentStatus.CLOSED.name());
            this.updateById(paymentInfo);
        }
    }

    /**
     * 根据订单Id支付方式查询本地交易记录
     *
     * @param orderId
     * @param paymentType
     * @return
     */
    @Override
    public PaymentInfo getPaymentInfo(Long orderId, String paymentType) {
        LambdaQueryWrapper<PaymentInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PaymentInfo::getOrderId, orderId);
        queryWrapper.eq(PaymentInfo::getPaymentType, paymentType);
        return this.getOne(queryWrapper);
    }
}
